package com.open.capacity.workflow3.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.open.capacity.commons.Result;
import com.open.capacity.model.system.SysUser;
import com.open.capacity.user.service.SysUserRelationService;
import com.open.capacity.user.service.SysUserService;
import com.open.capacity.utils.SysUserUtil;
import com.open.capacity.workflow3.engine.NwfScheme;
import com.open.capacity.workflow3.engine.NwfUserInfo;
import com.open.capacity.workflow3.entity.*;
import com.open.capacity.workflow3.service.NwfSchemeService;
import com.open.capacity.workflow3.service.NwfTaskService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.security.access.prepost.PreAuthorize;
import com.open.capacity.workflow3.service.NwfProcessService;

import com.open.capacity.commons.PageResult;

import javax.validation.Valid;

/**
 * @author
 * @email
 * @date 2023-11-02 21:21:15
 */
@Slf4j
@RestController
@RequestMapping("nwfprocess")
@Api(tags = "")
public class NwfProcessController {

    @Autowired
    private NwfProcessService processService;

    @Autowired
    private NwfSchemeService schemeService;

    @Autowired
    private NwfTaskService taskService;

    @Autowired
    private SysUserService userService;

    @Autowired
    private SysUserRelationService userRelationService;


    @GetMapping("/getPorcessList")
    public PageResult getPorcessList(@RequestParam Map<String, Object> param) {
        PageResult pageResult = processService.getPageList(param);
        return pageResult;
    }

    @GetMapping("/getTaskPageList")
    public PageResult getTaskPageList(@RequestParam Map<String, Object> param, String categoryId) {
        PageResult pageResult = new PageResult();
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        switch (categoryId) {
            case "1":
                pageResult = processService.getMyPageList(userInfo.getId(), param, null);
                break;
            case "2":
                pageResult = processService.getMyTaskPageList(userInfo, param, null, null);
                break;
            case "3":
                pageResult = processService.getMyFinishTaskPageList(userInfo, param, null);
                break;
        }

        return pageResult;
    }

    @GetMapping("/getBatchTaskPageList")
    public PageResult getBatchTaskPageList(@RequestParam Map<String, Object> param) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();

        PageResult<NwfProcess> myTaskPageList = processService.getMyTaskPageList(userInfo, param, null, true);

        return myTaskPageList;
    }

    @GetMapping("/getTask")
    public Result getTask(String taskId) {
        NwfTask data = taskService.getEntity(taskId);
        return Result.succeed(data);
    }

    @RequestMapping("/delete")
    public Result delete(String processId) {
        processService.delete(processId);
        return Result.succeed("删除成功");
    }

    @GetMapping("/getSchemeByCode")
    public Result getSchemeByCode(String code) {
        NwfSchemeinfo schemeInfo = schemeService.getInfoEntityByCode(code);
        if (schemeInfo != null) {
            com.open.capacity.workflow3.entity.NwfScheme data = schemeService.getSchemeEntity(schemeInfo.getSchemeId());
            return Result.succeed(data);
        }
        return Result.failed("找不到该流程模板");
    }

    @GetMapping("/getSchemeByProcessId")
    public Result getSchemeByProcessId(String processId) {
        NwfProcess processEntity = processService.findById(processId);
        if (processEntity != null) {
            if (StringUtils.isNotEmpty(processEntity.getSchemeId())) {
                com.open.capacity.workflow3.entity.NwfScheme data = schemeService.getSchemeEntity(processEntity.getSchemeId());
                return Result.succeed(data);
            }
            NwfSchemeinfo schemeInfo = schemeService.getInfoEntityByCode(processEntity.getSchemeCode());
            if (schemeInfo != null) {
                com.open.capacity.workflow3.entity.NwfScheme data2 = schemeService.getSchemeEntity(schemeInfo.getSchemeId());
                return Result.succeed(data2);
            }
        }
        return Result.failed("找不到该流程模板");
    }

    @GetMapping("/getNextAuditors")
    public Result getNextAuditors(String code, String processId, String taskId, String nodeId, String operationCode) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        Map<String, List<NwfUserInfo>> data = processService.getNextAuditors(code, processId, taskId, nodeId, operationCode, userInfo);
        return Result.succeed(data);
    }

    @GetMapping("/getProcessDetails")
    public Result getProcessDetails(String processId, String taskId) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        NwfProcessDetailsModel data = processService.getProcessDetails(processId, taskId, userInfo);
        if (StringUtils.isNotEmpty(data.getChildProcessId())) {
            processId = data.getChildProcessId();
        }
        List<NwfTask> taskNode = processService.getTaskUserList(processId);

        Map<String, Object> map = new HashMap<>();
        map.put("info", data);
        map.put("task", taskNode);

        return Result.succeed(map);
    }

    @GetMapping("/getChildProcessDetails")
    public Result getChildProcessDetails(String processId, String taskId, String schemeCode, String nodeId) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        NwfProcessDetailsModel data = processService.getChildProcessDetails(processId, taskId, schemeCode, nodeId, userInfo);
        List<NwfTask> taskNode = processService.getTaskUserList(data.getChildProcessId());
        Map<String, Object> map = new HashMap<>();
        map.put("info", data);
        map.put("task", taskNode);
        return Result.succeed(map);
    }

    @PostMapping("/saveDraft")
    public Result saveDraft(String processId, String schemeCode, String createUserId) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        if (StringUtils.isNotEmpty(createUserId) && !userInfo.getId().equals(createUserId)) {
            SysUser userEntity = userService.findById(createUserId);
            userInfo = userEntity;
        }
        processService.saveDraft(processId, schemeCode, userInfo);
        return Result.succeed("流程草稿保存成功");
    }

    @RequestMapping("/deleteDraft")
    public Result deleteDraft(String processId) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        processService.deleteDraft(processId, userInfo);
        return Result.succeed("流程草稿删除成功");
    }

    @PostMapping("/createFlow")
    public Result createFlow(String schemeCode, String processId, String processTitle, Integer processLevel, String auditors, String createUserId) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        if (StringUtils.isNotEmpty(createUserId) && !userInfo.getId().equals(createUserId)) {
            if (processTitle == null) {
                processTitle = "";
            }
            processTitle = processTitle + "【" + userInfo.getRealName() + "代发】";
            SysUser userEntity = userService.findById(createUserId);
            userInfo = userEntity;
        }
        try {
            processService.createFlow(schemeCode, processId, processTitle, processLevel, auditors, userInfo);
            return Result.succeed("ok", "流程创建成功");
        } catch (Exception ex) {
            log.error(ex.getMessage());
            processService.saveDraft(processId, schemeCode, userInfo);
            return Result.failed(ex.getMessage());
        }
    }

    @PostMapping("/createChildFlow")
    public Result createChildFlow(String schemeCode, String processId, String parentProcessId, String parentTaskId) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        processService.createChildFlow(schemeCode, processId, parentProcessId, parentTaskId, userInfo);
        return Result.succeed("流程创建成功");
    }

    @PostMapping("/againCreateFlow")
    public Result againCreateFlow(String processId) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        try {
            processService.againCreateFlow(processId, userInfo);
            return Result.succeed("流程重新创建成功");
        } catch (Exception ex) {
            return Result.failed(ex.getMessage());
        }
    }

    @RequestMapping("/auditFlow")
    public Result auditFlow(String operationCode, String operationName, String processId, String taskId, String des, String auditors, String stamp, String signUrl) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        try {
            processService.auditFlow(operationCode, operationName, processId, taskId, des, auditors, stamp, signUrl, userInfo);
            return Result.succeed("流程审批成功");
        } catch (Exception ex) {
            return Result.failed(ex.getMessage());
        }
    }

    @RequestMapping("/auditFlows")
    public Result auditFlows(String operationCode, String taskIds) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        processService.auditFlows(operationCode, taskIds, userInfo);
        return Result.succeed("流程批量审批成功");
    }

    @RequestMapping("/signFlow")
    public Result signFlow(String processId, String taskId, String userId, String des) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        processService.signFlow(processId, taskId, userId, des, userInfo);
        return Result.succeed("流程加签成功");
    }

    @RequestMapping("/signAuditFlow")
    public Result signAuditFlow(String operationCode, String processId, String taskId, String des) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        processService.signAuditFlow(operationCode, processId, taskId, des, userInfo);
        return Result.succeed("加签审批成功");
    }

    @RequestMapping("/referFlow")
    public Result referFlow(String processId, String taskId) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        processService.referFlow(processId, taskId, userInfo);
        return Result.succeed("保存成功");
    }

    @RequestMapping("/urgeFlow")
    public Result urgeFlow(String processId) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        processService.urgeFlow(processId, userInfo);
        return Result.succeed("催办成功");
    }

    @RequestMapping("/revokeFlow")
    public Result revokeFlow(String processId) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        processService.revokeFlow(processId, userInfo);
        return Result.succeed("撤销成功");
    }

    @GetMapping("/getTaskUserList")
    public Result getTaskUserList(String processId) {
        List<NwfTask> data = processService.getTaskUserList(processId);
        return Result.succeed(data);
    }

    @RequestMapping("/appointUser")
    public Result appointUser(String strList) {
        List<NwfTask> taskList = JSONObject.parseObject(strList, new TypeReference<List<NwfTask>>() {
        });
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        processService.appointUser(taskList, userInfo);
        return Result.succeed("指派成功");


    }

    @RequestMapping("/deleteFlow")
    public Result deleteFlow(String processId) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        processService.deleteFlow(processId, userInfo);
        return Result.succeed("作废成功");
    }

    @RequestMapping("/revokeAudit")
    public Result revokeAudit(String processId, String taskId) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        if (processService.revokeAudit(processId, taskId, userInfo)) {
            return Result.succeed("撤销成功");
        }
        return Result.failed("撤销失败，当前不允许撤销！");
    }

    @RequestMapping("/addTask")
    public Result addTask(String processId, String bNodeId, String eNodeId) {
        SysUser userInfo = SysUserUtil.getLoginAppUser();
        processService.addTask(processId, bNodeId, eNodeId, userInfo);
        return Result.succeed("添加成功");
    }
}
